package se.webbzon.oschi01.collision3d;

import java.util.ArrayList;
import java.util.Collection;

import javax.vecmath.Point3d;

public class CollisionCone3D extends CollisionModel3D {

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new collision cone with height 1 and radius 0.5.
	 * The base center of the cone will be placed in (0,-0.5,0). 
	 * The number of divisions (sides) will be equal to 18. 
	 * No cone base will be created if the cone is open. **/
	public CollisionCone3D(boolean open) {
		this(open,18);
	}
	
	/** Creates a new collision cone with height 1 and radius 0.5.
	 * The base center of the cone will be placed in (0,-0.5,0). 
	 * The number of divisions (sides) is given by the input. 
	 * No cone base will be created if the cone is open. **/
	public CollisionCone3D(boolean open, int divisions) {
		this(open,1,0.5,divisions);
	}
	
	/** Creates a new collision cone with a given height and radius.
	 * The base center of the cone will be placed in (0,-height/2,0).
	 * The number of divisions (sides) is given by the input.
	 * No cone base will be created if the cone is open. **/
	public CollisionCone3D(boolean open, double height, double radius, int divisions) {
		super(open ? 	createModelOpen(height,radius,divisions) :
						createModelClosed(height,radius,divisions));
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the closed collision model. **/
	private static Collection<CollisionTriangle3D> createModelClosed(
															double height,
															double radius,
															int divisions) {
		final double h = height/2, dv = 2*Math.PI/divisions;
		final Point3d top = new Point3d(0,h,0);
		final Point3d bottom = new Point3d(0,-h,0);
		final Point3d p1 = new Point3d(radius,-h,0);
		final Point3d p2 = new Point3d(0,0,0);
		final ArrayList<CollisionTriangle3D> vertices = new ArrayList<CollisionTriangle3D>();
		
		// Shape the cone
		for (int i = 0; i < divisions; i++) {
			p2.set(radius*Math.cos(i*dv),-h,radius*Math.sin(i*dv));
			vertices.add(new CollisionTriangle3D(top,p1,p2));
			vertices.add(new CollisionTriangle3D(bottom,p1,p2));
			p1.set(p2);
		}
		
		// Close the cone
		p2.set(radius,-h,0);
		vertices.add(new CollisionTriangle3D(top,p1,p2));
		vertices.add(new CollisionTriangle3D(bottom,p1,p2));
		
		return vertices;
	}
	
	/** Creates the open collision model. **/
	private static Collection<CollisionTriangle3D> createModelOpen(
															double height,
															double radius,
															int divisions) {
		final double h = height/2, dv = 2*Math.PI/divisions;
		final Point3d top = new Point3d(0,h,0);
		final Point3d p1 = new Point3d(radius,-h,0);
		final Point3d p2 = new Point3d(0,0,0);
		final ArrayList<CollisionTriangle3D> vertices = new ArrayList<CollisionTriangle3D>();
		
		// Shape the cone
		for (int i = 0; i < divisions; i++) {
			p2.set(radius*Math.cos(i*dv),-h,radius*Math.sin(i*dv));
			vertices.add(new CollisionTriangle3D(top,p1,p2));
			p1.set(p2);
		}
		
		// Close the cone
		p2.set(radius,-h,0);
		vertices.add(new CollisionTriangle3D(top,p1,p2));
		
		return vertices;
	}
	
}
